package com.xmall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmall.define.base.ResultCode;
import com.xmall.define.constants.CommonConstants;
import com.xmall.exception.XmallException;
import com.xmall.product.define.dict.AttrOptionTypeEnum;
import com.xmall.product.define.dto.saleAttr.SaleAttrDo;
import com.xmall.product.define.dto.saleAttr.SaleAttrDto;
import com.xmall.product.define.request.attr.SaleAttrQueryParams;
import com.xmall.product.define.request.attr.SaleAttrUpdateRequest;
import com.xmall.product.entity.SaleAttr;
import com.xmall.product.mapper.SaleAttrMapper;
import com.xmall.product.service.IAttrOptionService;
import com.xmall.product.service.ISaleAttrService;
import com.xmall.product.utils.ConvertUtils;
import com.xmall.utils.XmallUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 属性 服务实现类
 * </p>
 *
 * @author xmall
 * @since 2023-11-02
 */
@Service
public class SaleAttrServiceImpl extends ServiceImpl<SaleAttrMapper, SaleAttr> implements ISaleAttrService {

    @Resource
    private IAttrOptionService attrOptionService;

    /**
     * 新增
     */
    @Transactional
    @Override
    public void saveEntity(SaleAttrUpdateRequest request) {
        checkRepeatAttrName(request.getCategoryId(), request.getName());

        // 获取排序值
        Integer maxSort = this.baseMapper.getMaxSort(request.getCategoryId());
        request.setSort(null == maxSort ? CommonConstants.DEFAULT_SORT_NUM : maxSort + 1);

        SaleAttr saleAttr = ConvertUtils.SaleAttrModule.INSTANCE.toEntity(request);
        this.save(saleAttr);

        attrOptionService.save(saleAttr.getId(), AttrOptionTypeEnum.COMMON_SALE, request.getOptionList());
    }

    // 校验重复性（相同分类下的名称不能重复）
    private void checkRepeatAttrName(Long categoryId, String attrName) {
        List<String> nameList = this.list(new QueryWrapper<SaleAttr>().eq("category_id", categoryId)).stream().map(attr -> attr.getName()).collect(Collectors.toList());
        if(nameList.contains(attrName)) {
            throw new XmallException(ResultCode.PRODUCT_ATTR_NAME_REPEAT);
        }
    }

    /**
     * 编辑
     */
    @Transactional
    @Override
    public void updateEntity(SaleAttrUpdateRequest request) {
        SaleAttr entity = this.getById(request.getId());
        XmallUtils.notNull(entity);

        this.updateById(ConvertUtils.SaleAttrModule.INSTANCE.toEntity(request));

        attrOptionService.removeByAttrId(request.getId(), AttrOptionTypeEnum.COMMON_SALE);
        attrOptionService.save(request.getId(), AttrOptionTypeEnum.COMMON_SALE, request.getOptionList());
    }

    /**
     * 删除
     */
    @Transactional
    @Override
    public void deleteEntity(Long id) {
        this.removeById(id);
        attrOptionService.removeByAttrId(id, AttrOptionTypeEnum.COMMON_SALE);
    }

    /**
     * 交换排序值
     */
    @Transactional
    @Override
    public void swapSort(Long prevAttrId, Long nextAttrId) {
        SaleAttr prevAttr = this.getById(prevAttrId);
        SaleAttr nextAttr = this.getById(nextAttrId);

        XmallUtils.notNull(prevAttr);
        XmallUtils.notNull(nextAttr);

        SaleAttr updatePrevAttr = new SaleAttr();
        updatePrevAttr.setId(prevAttrId);
        updatePrevAttr.setSort(nextAttr.getSort());
        this.updateById(updatePrevAttr);

        SaleAttr updateNextAttr = new SaleAttr();
        updateNextAttr.setId(nextAttrId);
        updateNextAttr.setSort(prevAttr.getSort());
        this.updateById(updateNextAttr);
    }

    /**
     * 属性列表
     */
    @Override
    public List<SaleAttrDto> listWithCascade(SaleAttrQueryParams params) {
        List<SaleAttrDo> list = this.baseMapper.listWithCascade(params);
        return ConvertUtils.SaleAttrModule.INSTANCE.doList2DtoList(list);
    }

    /**
     * 详情
     */
    @Override
    public SaleAttrDto infoWithCascade(Long id) {
        SaleAttrDo entity = this.baseMapper.infoWithCascade(id);
        XmallUtils.notNull(entity);
        return ConvertUtils.SaleAttrModule.INSTANCE.do2Dto(entity);
    }
}
